package controller;


import java.net.Socket;
import java.util.HashMap;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;


import javax.swing.JOptionPane;

import dao.DaoException;
import model.AppModel;
import model.Filter;

import model.ModelException;

import view.AppView;
import view.IncomingMeeting;

/**
 * The main application controller
 * 
 * It holds a reference to the model and the view at all times and nests under its belt
 * all the other controllers for different views
 * @author MUSAB
 *
 * @version $Revision: 1.0 $
 */
public class AppController{
	
	/**
	 * System configurations
	 */
	protected Properties config;

	/**
	 * The application model
	 */
	protected AppModel model;
	
	/**
	 * The application view
	 */
	protected AppView view;

	// Controllers
	private ListingController listingController;
	private NavigationController navigationController;
	private MenuController menuController;
	private PreviewController previewController;
	private Timer timer = new Timer();
	
	
	/**
	 * Constructor for controller.
	 * 
	 * The controller has direct access to the model and view
	 * @param model The application model
	 * @param view The application view
	
	 * @throws ControllerException  */
	public AppController(AppModel model, AppView view) throws ControllerException {
		this.model = model;
		this.view = view;
		init();
	}

	/**
	 * Begins the application
	
	 * @throws ControllerException  */
	public void init() throws ControllerException{
		
		// Tell the model to init the DAO
		try {
			model.initDao();
		} catch (DaoException e) {
			throw new ControllerException();
		}
		
		// Init controllers
		listingController = new ListingController(model, view, this);
		menuController = new MenuController(model, view, this);
		navigationController = new NavigationController(model, view, this);
		previewController = new PreviewController(model, view, this);
		
		loadUser();
//		IncomingMeeting meeting=new IncomingMeeting();
//		meeting.showDialog();
		
		//apply filter every 10 minutes .schedule() takes milliseconds argument
//		timer.schedule(new PeriodicFilter(model,view,this), 0,10*60*1000);
//		
//		startConnectionMaintainer();
		
		// This is temporary, merge back later:
//		new Thread(new ServerListener(model)).start();
		
		new Thread(new ServerConnector(this, model)).start();
		
		
	}
	
	/**
	 * Sets up and starts thr server connector controller
	 * which tries to keep connecting to the server
	 */
	public void startConnectionMaintainer(){

		ConnectionMaintainer connectionMaintainer = new ConnectionMaintainer(this, model);
		Timer timer = new Timer();
		timer.schedule(connectionMaintainer, 0, 5000);
		
	}
	
	/**
	 * Tries to load the user
	
	 * @throws ControllerException  */
	private void loadUser() throws ControllerException{
		
		String username = JOptionPane.showInputDialog("Enter your username:");
		if (username == null){
			System.exit(0);
		}
		
		// Sanitize username
		username = username.toLowerCase().trim();
		
		while(username.equals("")){
			username = JOptionPane.showInputDialog("Empty input, please enter a valid username:");
			username = username.toLowerCase().trim();
		}
		
		// Try to load that user
		if (!model.loadAccount(username)){
			if (JOptionPane.showConfirmDialog(null, "Could not locate your account, create a new one with username: " + username + "?", "WARNING",JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
				
				// Create new user account
				try {
					model.createAccount(username);
				} catch (ModelException e) {
					throw new ControllerException(e.getMessage());
				}
				
			} else {
				System.exit(0);
			}
		}
		
		navigationController.refreshNavigationFolders(null);
		view.init();
	}

	/**
	 * Listing controller getter
	
	 * @return the listingController */
	public ListingController getListingController() {
		return listingController;
	}

	/**
	 * Navigation controller getter
	
	 * @return the navigationController */
	public NavigationController getNavigationController() {
		return navigationController;
	}

	/**
	 * Menu controller getter
	
	 * @return the menuController */
	public MenuController getMenuController() {
		return menuController;
	}

	/**
	 * Preview controller getter
	
	 * @return the previewController */
	public PreviewController getPreviewController() {
		return previewController;
	}
	
	/**
	 * Makes a notification
	 * 
	 * @param messageType
	 * @param message
	 */
	public void notify(String messageType, String message){
		navigationController.notify(messageType, message);
	}


}

class PeriodicFilter extends TimerTask {
	
	AppModel model;
	AppView view;
	AppController controller;
    public PeriodicFilter(AppModel model,AppView view,AppController controller) {
		this.model=model;
		this.view=view;
		this.controller=controller;
	}

	@Override
    public void run() {
       
        
        //Get all user's filters
        for(Filter filter: model.getUser().getFilters())
        {

        model.applyFilter(filter);
        
        }
        // refresh view
        controller.getNavigationController().refreshNavigationFolders(model.getCurrentFolderName());
       
    }
}
